<template>
  <Modal v-model="isOPen" :title="title||'编辑'" :width="curWidth" @on-cancel="cancel" :scrollable='true' @on-visible-change='visibleChange' :mask-closable='false'>

    <Form v-if="isRefresh" class="modal-form" ref="From" :model="row" :label-width="120" inline>
      <div class="line-row">
        <FormItem>
          <slot name="top">
          </slot>
        </FormItem>
      </div>

      <template v-for="col in curColumns">
        <div :class="col.inLine?'inline-row':'line-row'" :key="col.name" v-if="col.key&&!col.display">
          <FormItem :label="col.title" :prop="col.key" :rules="curRules[col.key]" :style=" col.rowStyle">
            <Row>

              <Select class="text-left" filterable v-if="col.com==='Select'" v-model='row[col.key]' v-bind="col">
                <Option :value="item.key" :key="item.key" v-for="item in col.source">{{item.value }}</Option>
              </Select>

              <RadioGroup v-else-if="col.com==='Radio'" v-model="row[col.key]" v-bind="col">
                <Radio :label="item.key" :key="item.key" v-for="item in col.source">
                  {{item.value}}
                </Radio>
              </RadioGroup>

              <AutoComplete v-else-if="col.com==='SelectIcon'" icon="ios-search" v-model="row[col.key]" v-bind="col">
                <Option v-for="(icon,index) in icons" :value="icon" :key="index">
                  <Icon size="20" :type="icon" />
                  {{ icon }}
                </Option>
              </AutoComplete>

              <UploadSingle v-else-if="col.com==='upload_Img'" v-model="row[col.key]" v-bind="col">

              </UploadSingle>

              <TextArea v-else-if="col.com==='TextArea'" v-model="row[col.key]" v-bind="col">

              </TextArea>

              <templateRender v-else-if="col.editRender" :value="row[col.key]" :render='col.editRender'></templateRender>

              <Input v-else-if="!col.com" v-model="row[col.key]" v-bind="col" style="width:100%;" />

              <component v-else v-bind:is="col.com" v-model="row[col.key]" v-bind="col"></component>

            </Row>
          </FormItem>
        </div>
      </template>

      <slot name='bottom'></slot>

    </Form>

    <div slot="footer">
      <Button type="primary" @click="save">确定</Button>
    </div>
  </Modal>
</template>
<script>
import Vue from 'vue'
import dayjs from 'dayjs'
import templateRender from './templateRender'
const icons = require('@/config/icons')
export default {
  props: ['columns', 'width'],
  components: {
    templateRender,
  },
  data() {
    return {
      title: '新增',
      isRefresh: true,
      isEdit: false,
      isOPen: false,
      icons: [],
      row: {},
      callback: null,
    }
  },

  computed: {
    curWidth() {
      return this.width || '80'
    },
    curColumns() {
      if (this.columns) {
        return this.columns.filter((p) => p.type !== 'template' && p.key !== 'id')
      }
      return []
    },

    curRules() {
      let ruleObj = {}
      let ruleCols = this.columns.filter((p) => p.required)
      if (ruleCols) {
        ruleCols.forEach((col) => {
          let com = col.com || 'Input'
          let trigger = com === 'Input' ? 'blur' : 'change'

          if (com === 'Input') {
            ruleObj[col.key] = [{ required: true, message: `${col.title}不能为空`, trigger }]
          } else if (com === 'Select') {
            ruleObj[col.key] = [{ required: true, type: 'number', message: `${col.title}不能为空`, trigger }]
          }
        })
      }
      return this.$attrs.rules || ruleObj
    },
  },
  methods: {
    refresh() {
      this.isRefresh = false
      this.$nextTick(() => {
        this.isRefresh = true
      })
    },
    visibleChange(res) {
      this.$emit('on-visible-change', res)
    },

    editShow(row, callback) {
      this.title = '编辑'
      this.isEdit = true
      this.init(row)
      this.show()
      this.callback = callback
    },
    addShow(row, callback) {
      this.title = '新增'
      this.isEdit = false
      this.init(row)

      this.show()
      this.callback = callback
    },
    show() {
      this.refresh()
      this.isOPen = true
    },
    hide() {
      this.isOPen = false
    },
    async init(row, isgl) {
      this.icons = icons.map((item) => item.trim())
      row = row || {}
      let rules = this.curRules
      if (isgl) {
        this.row = JSON.parse(JSON.stringify(row))
      } else {
        this.row = row
      }

      let keys = Object.keys(rules)
      if (keys && keys.length > 0) {
        this.$refs['From'].resetFields()
      }

      this.curColumns
        .filter((p) => p.key !== undefined)
        .forEach((col) => {
          let defaultVal = row[col.key]

          if (col.data_type === 'number') {
            defaultVal = parseFloat(defaultVal) || 0
            Vue.set(this.row, col.key, defaultVal)
          } else if (col.data_type === 'date') {
            Vue.set(this.row, col.key, dayjs(defaultVal).toDate())
          } else if (col.data_type === 'boolean') {
            Vue.set(this.row, col.key, false)
          } else {
            defaultVal = defaultVal !== undefined ? defaultVal : ''
            Vue.set(this.row, col.key, defaultVal)
          }
        })
    },
    async save() {
      let rules = this.curRules
      let keys = Object.keys(rules)

      if (keys && keys.length > 0) {
        let validate = await this.$refs['From'].validate()
        if (!validate) {
          Promise.reject(new Error('请检查表单'))
          this.$Message.error('请检查表单')
          return
        }
      }

      let row = JSON.parse(JSON.stringify(this.row))

      let dateCols = this.curColumns.filter((p) => p.type === 'date')
      if (dateCols && dateCols.length > 0) {
        dateCols.forEach((col) => {
          let format = col.type === 'date' ? 'YYYY-MM-DD' : 'YYYY-MM-DD HH:mm:ss'
          row[col.key] = dayjs(row[col.key]).format(format)
        })
      }

      if (this.callback) {
        await this.callback(row)
        this.hide()
      }
    },
    cancel() {},
  },
}
</script>
<style lang="less" scoped>
.inline-row {
  display: inline-block;
  width: 50%;
  .ivu-form-item {
    width: 100%;
    margin-bottom: 10px;
  }
}

.line-row {
  display: block;
  text-align: left;
  margin-top: 0.1rem;
  .ivu-form-item {
    width: 90%;
  }
}
.ivu-radio-wrapper {
  margin-left: 20px;
}

.ivu-date-picker {
  width: 100%;
}

.text-left {
  text-align: left;
}
</style>
